package ru.nstu.isma.core.lang.ast.visitor;

import ru.nstu.isma.core.lang.ast.LismaBaseVisitor;
import ru.nstu.isma.core.lang.ast.LismaParser;
import ru.nstu.isma.core.hsm.HMConst;
import ru.nstu.isma.core.hsm.HMUnnamedConst;
import ru.nstu.isma.core.hsm.HMVariable;
import ru.nstu.isma.core.hsm.HMVariableTable;
import ru.nstu.isma.core.hsm.pde.HMApproximateVariable;
import ru.nstu.isma.core.hsm.pde.HMPDEBound;
import ru.nstu.isma.core.hsm.pde.HMPartialDerEquation;
import org.antlr.v4.runtime.misc.NotNull;

/**
 * by
 * Bessonov Alex.
 * Date: 04.12.13 Time: 1:07
 */
public class BoundInfoVisitor extends LismaBaseVisitor<HMPDEBound> {
    private HMVariableTable table;

    public BoundInfoVisitor(HMVariableTable table) {
        this.table = table;
    }

    @Override
    public HMPDEBound visitEdge(@NotNull LismaParser.EdgeContext ctx) {
        HMPDEBound bound = new HMPDEBound();

        // 1 ищем ДУЧП для края
        LismaParser.Edge_eqContext eq = (LismaParser.Edge_eqContext) ctx.getChild(1);
        HMVariable v = table.get(eq.getChild(0).getText());
        if (v == null || !(v instanceof HMPartialDerEquation)) {
            //TODO ошибка семантики
        }
        HMPartialDerEquation derEquation = (HMPartialDerEquation) v;
        bound.setEquation(derEquation);

        // 2 ставим значение края
        HMConst val = new HMUnnamedConst(Double.valueOf(eq.getChild(2).getText()));
        table.add(val);
        bound.setValue(val);

        // 3 ищем переменную
        // TODO добавить проверку
        HMApproximateVariable av = (HMApproximateVariable) table.get(ctx.getChild(3).getText());
        bound.setAtApxVar(av);

        //4 смотрим тип края
        String type =  ctx.getChild(4).getText();
        if (type.equals("left")) {
            bound.setSide(HMPDEBound.Type.LEFT);
        } else if (type.equals("right")) {
            bound.setSide(HMPDEBound.Type.RIGHT);
        } else if (type.equals("both")) {
            bound.setSide(HMPDEBound.Type.BOTH);
        }
        // добавим край
        derEquation.addBound(bound);
        return super.visitEdge(ctx);    //To change body of overridden methods use File | Settings | File Templates.
    }

    @Override
    public HMPDEBound visitEdge_eq(@NotNull LismaParser.Edge_eqContext ctx) {
        return super.visitEdge_eq(ctx);    //To change body of overridden methods use File | Settings | File Templates.
    }
}
